package com.huaxindata.im.main.contactview.group;

import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.huaxin.common.view.avatarimageview.AvatarImageView;
import com.huaxindata.common.http.ResponseBean;
import com.huaxindata.common.util.DialogUtil;
import com.huaxindata.common.util.ToastUtil;
import com.huaxindata.common.view.ExpandGridView;
import com.huaxindata.common.view.ToggleButton;
import com.huaxindata.im.R;
import com.huaxindata.im.constants.ImConstants;
import com.huaxindata.im.http.RetrofitClient;
import com.huaxindata.im.main.chat.ConversationManager;
import com.huaxindata.im.main.manager.ContactManager;
import com.huaxindata.im.main.manager.HistoryContactManager;
import com.huaxindata.im.main.manager.UserManager;
import com.huaxindata.im.model.contact.Contact;
import com.huaxindata.im.model.contact.ContactGroup;
import com.huaxindata.im.model.contact.ContactPerson;
import com.huaxindata.im.model.db.MessageStore;
import com.huaxindata.im.model.entity.ChatMessage;
import com.huaxindata.im.model.entity.ChatMessageBody;
import com.huaxindata.im.model.entity.ChatSysMessageBody;
import com.huaxindata.im.service.MessageService;
import com.huaxindata.im.util.Log;
import com.huaxindata.im.util.SharePreferenceUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * 本类主要是用于显示群组的详细资料，另有如下功能
 * 1、邀请其它好友加入
 * 2、如果是群主还可以踢人
 * 3、删除聊天记录
 * 4、解散群或退群
 */
public class GroupInfoActivity extends AppCompatActivity implements
        ContactManager.OnContactRefresh,AdapterView.OnItemClickListener{

    public static final String TAG = "GroupInfoActivity";

    private Toolbar mToolbar;//工具条
    private TextView mGroupNameTv;//群组名

    private ExpandGridView mGroupMemberGridv;//展示群成员的gridView

    private TextView mGroupMemberNum;//群成员数量

    private AvatarImageView mGroupIcon;//群头像

    private TextView group_nickname;//群昵称

    private TextView leaveOrDestroy;//针对群的操作，中退群还是解散群

    private ToggleButton mIgnoreMessageToggle;//忽略群消息

    //群成员数量的信息
    private String mGroupMemberNumStr;
    File file;
    ContactGroup mGroup;
    private SimpleAdapter mAdapter;
    List<Contact> mGroupMemberList;
    private String[] mGroupMemberId;

    private boolean mIsBind = false;
    private MessageService mMessageService;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_info);
        bindToService();
        mGroup= (ContactGroup) ConversationManager.getChatObject();
        Log.e("lwjing","chatObject:"+mGroup.toString());
        initView();
        initData();
    }

    public void initView() {
        mToolbar = (Toolbar) findViewById(R.id.group_info_toolbar);
        mGroupNameTv = (TextView) findViewById(R.id.group_info_name);
        mGroupIcon = (AvatarImageView) findViewById(R.id.group_info_icon);
        mGroupMemberGridv = (ExpandGridView) findViewById(R.id.group_info_member_grid);
        mGroupMemberNum=(TextView)findViewById(R.id.group_info_member_num);
        group_nickname = (TextView) findViewById(R.id.group_info_nickname);
        leaveOrDestroy = (TextView) findViewById(R.id.group_info_leaveOrDestroy);
        mIgnoreMessageToggle = (ToggleButton) findViewById(R.id.group_info_message_ignore);
        setSupportActionBar(mToolbar);
        mToolbar.setTitle("群信息");
        mIgnoreMessageToggle.setOnToggleChanged(new ToggleButton.OnToggleChanged() {
            @Override
            public void onToggle(boolean on) {
                //在这里要实现可以过滤群消息，不通知给用户
                SharePreferenceUtil.setBoolean(GroupInfoActivity.this,"group_"+mGroup.getClientId(),on);
            }
        });
        if (SharePreferenceUtil.getBoolean(this, "group_" + mGroup.getClientId(), false)) {
            mIgnoreMessageToggle.setToggleOn();
        } else {
            mIgnoreMessageToggle.setToggleOff();
        }
    }
    public void initData() {
        mGroupNameTv.setText(mGroup.getNickName());
        group_nickname.setText(mGroup.getNickName());
        //如果是群主
        if (UserManager.getClientId().equals(mGroup.getGroupMain())) {
            leaveOrDestroy.setText("解散群");
        } else {
            leaveOrDestroy.setText("离开群");
        }
        mGroup.showImageIcon(this,mGroupIcon, null);
        if (true) {//在这里获取是否忽略群消息的设置
            mIgnoreMessageToggle.setToggleOn();
        } else {
            mIgnoreMessageToggle.setToggleOff();
        }
        initGridView();
    }

    /**
     *
     *初始化群成员的网格列表
     *@author:guokailin
     *time:2017/6/16 11:41
     */
    private void initGridView() {
        if ( mGroup.getGroupMembers() == null){
            return;
        }
        mGroupMemberNumStr = getResources().getString(R.string.new_group_people_select);
        if (mAdapter == null) {
            mAdapter = new SimpleAdapter(this);
            mGroupMemberGridv.setAdapter(mAdapter);
            mGroupMemberGridv.setOnItemClickListener(this);
            mGroupMemberGridv.setOverScrollMode(View.OVER_SCROLL_NEVER);
            mGroupMemberList = new ArrayList<>();
        }
        mGroupMemberList.clear();
        mGroupMemberId = mGroup.getGroupMembers().split(",");
        String[] name = mGroup.getGroupMembersNickName().split(",");
        String[] icon = mGroup.getGroupMembersImg().split(",");
        int count= mGroupMemberId.length;
        mGroupMemberNum.setText(String.format(mGroupMemberNumStr, count));
        for (int i=0;i<count;i++){
            ContactPerson person = new ContactPerson(mGroupMemberId[i], name[i], icon[i].trim());
            mGroupMemberList.add(person);
        }
        bindData(mGroupMemberList);
    }
    /**
     *
     *给群成员gridView绑定数据
     *@author:guokailin
     *time:2017/6/16 16:43
     */
    private void bindData(List<Contact> contactList) {
        ArrayList<Object> objects = new ArrayList<>();
        objects.addAll(contactList);
        if (mGroup.getGroupMain().equals(UserManager.getClientId())) {
            objects.add("add");
            objects.add("del");
        }
        mAdapter.setData(objects);
        mAdapter.notifyDataSetChanged();
    }

    @Override
    public void onRefresh() {
        //退群或更新群信息之后都要刷新群数据，故回调此方法
        initData();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (mGroup.getGroupMain().equals(UserManager.getClientId())) {
            if (mAdapter.getData().size() - 2 == position) {
                addPeoples();
            } else if (mAdapter.getData().size() - 1 == position) {
                delPeoples();
            }
        }
    }

    /**
     * 整个activity中的事件监听回调
     * @param view
     */
    public void groupInfoOnClick(View view) {
        int viewId = view.getId();
        if (viewId==R.id.group_info_icon){
            if (isGroupMain()) {
                showOrHideRouteInfo(true, 0);
            }
        } else if (viewId == R.id.group_info_clear_record) {
            clearRecord();//清除聊天记录
        } else if (viewId == R.id.group_info_leaveOrDestroy) {
            if (isGroupMain()) {//解散群
                destroyGroup(mGroup);
            } else {//退群
                if (mGroupMemberId==null){
                    ToastUtil.showToast(this,"当前群可能不存在");
                    return;
                }
                leaveGroup();
            }
        } else if (viewId == R.id.group_info_bottom__camera) {
            showOrHideRouteInfo(false, 1);
        } else if (viewId == R.id.group_info_bottom_picture) {
            showOrHideRouteInfo(false, 2);
        } else if (viewId == R.id.group_info_bottom_cancel) {
            showOrHideRouteInfo(false, 0);
        }
    }
    //解散群
    private void destroyGroup(final ContactGroup group){
        Call<ResponseBean> call = RetrofitClient.getHttpApi().deleteGroup(group.getGroupClientId());
        call.enqueue(new Callback<ResponseBean>() {
            @Override
            public void onResponse(Call<ResponseBean> call, Response<ResponseBean> response) {
                ResponseBean responseBean = response.body();
                if (response.isSuccessful() && responseBean !=null){
                    if (responseBean.getState() == 1) {
                        ContactManager.initData();
                        MessageStore.deleteGroupMsg(group.getClientId());
                        HistoryContactManager.deleteHistory(group.getClientId());
                        sendDestroyGroupSystemMessage(mGroup);
                        ToastUtil.showToast(GroupInfoActivity.this,"群解散成功");
                        Log.e("xxx","xxx==群消息界面解散群");
                        setResult(ImConstants.RESULT_CODE_EXIT);
                        finish();
                    }else{
                        ToastUtil.showToast(GroupInfoActivity.this,responseBean.getMsg());
                    }
                }else{
                    ToastUtil.showToast(GroupInfoActivity.this,"解散群失败，请重新操作");
                }

            }
            @Override
            public void onFailure(Call<ResponseBean> call, Throwable t) {
                ToastUtil.showToast(GroupInfoActivity.this,"解散群失败，请检查网络");
            }
        });
    }

    /**
     * 解散群，向所有的群成员发送解散群消息
     * 消息格式："destroyGroup #& 群id #& 群名称"
     *@author:guokailin
     *time:2017/6/19 14:13
     */
    public void sendDestroyGroupSystemMessage(ContactGroup group) {
        String[] members=group.peoples;
        for (String memberId : members) {
            if (UserManager.getClientId() .equals(memberId)){
                //避免自己给自己发送消息
                Log.e("lwjing","解散群不给自己发消息");
                continue;
            }
            ChatMessage message=new ChatMessage(ChatMessageBody.Type.SYSTEM,group.getClientId(),memberId,System.currentTimeMillis());
            ChatSysMessageBody chatSysMessageBody=new ChatSysMessageBody(ChatMessageBody.Type.SYSTEM);
            chatSysMessageBody.action=ChatSysMessageBody.SysMessageType.ACTION_DESTROY_GROUP;
            chatSysMessageBody.content=chatSysMessageBody.action+ChatMessage.PREX + group.getClientId() + ChatMessage.PREX + group.getNickName();
            message.messageBody=chatSysMessageBody;
            sendMessage(message);
        }
        //由于订阅是持久化订阅，所以在解散群、退出群和删除好友都要取消订阅
        mMessageService.unSubscribe(group.getClientId());

    }

    private void sendMessage(ChatMessage message){
        String topic = "chat/" + message.receiver;
        mMessageService.sendMessage(topic, message,null);
    }


    /**
     * 绑定到后台接收消息的service
     */
    private void bindToService() {
        Intent intent = new Intent(this, MessageService.class);
        bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
        mIsBind = true;
    }

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMessageService = ((MessageService.MyBinder) service).getService();
            mIsBind = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mMessageService = null;
            mIsBind = false;
        }
    };

    private void unBindService() {
        if (mIsBind) {
            unbindService(mServiceConnection);
            mIsBind = false;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unBindService();
    }

    /**
     * 退群
     */
    private void leaveGroup(){
        final Dialog dialog = DialogUtil.getConfirmDialog(this, null, "是否退出该群?", "确认", "取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(final DialogInterface dialog, int which) {
                int length = mGroupMemberId.length;
                StringBuffer sb = new StringBuffer();
                for (int i=0;i< length;i++) {
                    String id=mGroupMemberId[i];
                    if (id.equals(UserManager.getClientId())) {
                        continue;
                    }
                    sb.append(id);
                    if (i != length - 1) {
                        sb.append(",");
                    }
                }
                updateGroupInfo(null,mGroup.getGroupName(),sb.toString(),false);
                ContactManager.initData();
                dialog.dismiss();
            }
        }, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        }).create();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }
    /**
     * 更新群图标、群昵称、添加踢除群成员
     * @param file:更新群图标
     * @param groupName：修改群名称
     * @param memberId：修改后的群成员Id
     * @param flag:标志是退群还是更新群信息，true表示更新群信息，false表示退群
     */
    private void updateGroupInfo(final File file, String groupName, String memberId, final boolean flag) {
        final String tip ="更新中";
        final Dialog dialog = DialogUtil.getWaitDialog(this, tip);
        if (dialog.isShowing()) {
            return;
        }
        dialog.show();
        MultipartBody.Part part = null;
        if (file != null) {
            RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
        }
        Callback<ContactGroup> callback = new Callback<ContactGroup>() {
            @Override
            public void onResponse(Call<ContactGroup> call, Response<ContactGroup> response) {
                dialog.dismiss();
                if (response.isSuccessful()) {
                    ContactGroup model = response.body();
                    if (model == null) {
                        ToastUtil.showToast(GroupInfoActivity.this, "更新群资料失败");
                        return;
                    }
                    if (flag) {//如果是更新群，包括增加群成员和删除群成员
                        ToastUtil.showToast(GroupInfoActivity.this, "更新群资料成功");
//                        ContactManager.initData();//更新群数据
                        ConversationManager.sendUpdateGroupSystemMessage(model);
                    } else {//退出群
                        Log.e("xxx","xxxx==群消息界面退出群");
                        setResult(ImConstants.RESULT_CODE_EXIT);//设置ConversationActivity退出
                        ContactManager.removeGroup(mGroup.groupClientId);
                        ConversationManager.sendLeaveGroupSystemMessage(model);
                        finish();
                    }
                }
            }
            @Override
            public void onFailure(Call<ContactGroup> call, Throwable t) {
                Log.e("xxx","xxx==更新群资料失败");
            }
        };
        //异步向服务器提交创建群的信息
        if (part == null) {
            RetrofitClient.getHttpApi().createGroup(groupName, memberId).enqueue(callback);
        } else {
            RetrofitClient.getHttpApi().createGroupWithPic(part, groupName, memberId).enqueue(callback);
        }
    }
    private boolean isGroupMain(){
        return UserManager.getClientId().equals(mGroup.getGroupMain());
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == android.R.id.home) {
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

    private class SimpleAdapter extends BaseAdapter{
        private Context mContext;
        private LayoutInflater mInflater;
        private List<Object> mList;
        public SimpleAdapter(Context context){
            this.mContext=context;
            mInflater = LayoutInflater.from(context);
        }
        public void setData(List<Object> list){
            this.mList=list;
        }
        public List<Object> getData(){
            return mList;
        }
        @Override
        public int getCount() {
            return mList==null?0:mList.size();
        }

        @Override
        public Object getItem(int position) {
            return mList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int index, View view, ViewGroup parent) {
            final Holder holder;
            if (view == null) {
                view = mInflater.inflate(R.layout.group_member_item, parent,false);
                holder = new Holder(view);
                view.setTag(holder);
            } else {
                holder = (Holder) view.getTag();
            }
            Object o = getData().get(index);
            if (o instanceof Contact) {
                holder.icon_add.setVisibility(View.GONE);
                holder.icon_del.setVisibility(View.GONE);
                Contact contact = (Contact) o;
                contact.showImageIcon(mContext, holder.icon, holder.iv_icon_expand);
            } else if ("add".equals(o)) {
                holder.icon_add.setVisibility(View.VISIBLE);
                holder.icon_del.setVisibility(View.GONE);
                holder.icon.setVisibility(View.GONE);
                holder.iv_icon_expand.setVisibility(View.GONE);
            } else if ("del".equals(o)) {
                holder.icon_del.setVisibility(View.VISIBLE);
                holder.icon_add.setVisibility(View.GONE);
                holder.icon.setVisibility(View.GONE);
                holder.iv_icon_expand.setVisibility(View.GONE);
            }
            return view;
        }
        private class Holder {
            View icon_add, icon_del;
            AvatarImageView icon;
            TextView        iv_icon_expand;
            public Holder(View view){
                this.icon = (AvatarImageView) view.findViewById(R.id.group_member_item_icon);
                this.iv_icon_expand = (TextView) view.findViewById(R.id.group_member_item_icon_expand);
                this.icon_add = view.findViewById(R.id.group_member_item_add);
                this.icon_del = view.findViewById(R.id.group_member_item_delete);
            }
        }
    }
    /**
     *
     *向群内添加成员
     *@author:guokailin
     *time:2017/6/16 16:19
     */
    public void addPeoples() {
        //如果好友列表中已经有好友在群里则要排除掉
        List<Contact> friendList = ContactManager.getFriendList();
        List<Contact> selectableList = new ArrayList<>();
        for (Contact friend : friendList) {
            boolean flag=true;
            String friendId = friend.getClientId();
            for (Contact groupMember : mGroupMemberList) {
                if (groupMember.getClientId().equals(friendId)) {
                    flag = false;//不放在可选列表中
                    break;
                }
            }
            if (flag) {
                selectableList.add(friend);
            }
        }
        if (selectableList.size() == 0) {
            ToastUtil.showToast(this,"你的所有好友都已经在该群里");
            return;
        }
        SelectMemberPresenter.setSelectableMember(selectableList);
        Intent intent = new Intent(this, SelectGroupMemberActivity.class);
        intent.putExtra(ImConstants.FUNCTION_SELECT_GROUP_MEMBER, ImConstants.FUNCTION_ADD_MEMBER);
        startActivityForResult(intent, ImConstants.REQUEST_CODE);
    }
    /**
     *
     *删除群内成员
     *@author:guokailin
     *time:2017/6/16 16:19
     */
    public void delPeoples() {
        //群成员第一个人是自己，要踢除
        List<Contact> list = mGroupMemberList.subList(1, mGroupMemberList.size());
        SelectMemberPresenter.setSelectableMember(list);
        Intent intent = new Intent(this, SelectGroupMemberActivity.class);
        intent.putExtra(ImConstants.FUNCTION_SELECT_GROUP_MEMBER, ImConstants.FUNCTION_DELETE_MEMBER);
        startActivityForResult(intent, ImConstants.REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode != ImConstants.REQUEST_CODE) {
            return;
        }
        if (resultCode == ImConstants.FUNCTION_ADD_MEMBER) {//要增加群成员
            addGroupMember(SelectMemberPresenter.getSelectedList());
        } else if (resultCode == ImConstants.FUNCTION_DELETE_MEMBER) {//群组里踢除人
            deleteGroupMember(SelectMemberPresenter.getSelectedList());
        }
    }

    /**
     * 更新群成员，list中的群成员是要增加的
     * @param list
     */
    private void addGroupMember(List<Contact> list){
        StringBuffer sb = new StringBuffer();
        //原来的群成员
        for (Contact member : mGroupMemberList) {
            sb.append(member.getClientId());
            sb.append(",");
        }
        //新加入的群成员
        for (Contact member : list) {
            sb.append(member.getClientId());
            sb.append(",");
        }
        sb.deleteCharAt(sb.lastIndexOf(","));
        updateGroupInfo(null,mGroup.getGroupName(),sb.toString(),true);
        mGroupMemberList.addAll(list);
        bindData(mGroupMemberList);
    }
    private void deleteGroupMember(List<Contact> list){
        if (list.size() == mGroupMemberList.size()) {
            ToastUtil.showToast(this,"不能踢除所有群成员");
            return;
        }
        StringBuffer sb = new StringBuffer();
        for (Contact member : mGroupMemberList) {
            boolean flag=false;//标记是否要删除该id的群成员
            String memberId=member.getClientId();
            for (Contact contact : list) {
                String id=contact.getClientId();
                if (memberId.equals(id)) {
                    flag=true;
                    break;
                }
            }
            if (flag) {
                mGroupMemberList.remove(member);//从当前群成员中删去
            } else {//剩余留在群里的成员id
                sb.append(memberId);
                sb.append(",");
            }
        }
        sb.deleteCharAt(sb.lastIndexOf(","));//删除最后一个逗号
        updateGroupInfo(null,mGroup.getGroupName(),sb.toString(),true);
        bindData(mGroupMemberList);
    }
    /**
     * 清除聊天记录
     */
    public void clearRecord() {
        final Dialog dialog = DialogUtil.getConfirmDialog(this, null, "是否清空记录?", "确认", "取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                MessageStore.deleteGroupMsg(mGroup.getClientId());
                dialog.dismiss();
                Toast toast = Toast.makeText(GroupInfoActivity.this, "记录已清空", Toast.LENGTH_SHORT);
                toast.show();
            }
        }, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        }).create();
        dialog.show();
    }

    @Override
    public void onPause() {
        super.onPause();
        ContactManager.removeContactRefreshListenner(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        ContactManager.addContactRefreshListenner(this);
    }
    private int bottomViewHeight;
    View bottomView, bottomPanel;
    void showOrHideRouteInfo(final boolean show, final int type) {
        if (bottomViewHeight == 0) {
            bottomView = findViewById(R.id.group_info_bottom_layout);
            bottomPanel = findViewById(R.id.group_info_bottom_panel);
            int height = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            bottomView.measure(0, height);
            bottomViewHeight = bottomView.getMeasuredHeight();
        }
        final ObjectAnimator animator;
        if (show) {
            bottomPanel.setVisibility(View.VISIBLE);
            animator = ObjectAnimator.ofFloat(bottomView, "translationY", bottomViewHeight, 0);
        } else {
            bottomPanel.postDelayed(new Runnable() {
                @Override
                public void run() {
                    bottomPanel.setVisibility(View.GONE);
                    if (type > 0) {
                        startWithType(type);
                    }
                }
            }, 300);
            animator = ObjectAnimator.ofFloat(bottomView, "translationY", 0, bottomViewHeight);
        }
        animator.setDuration(300);
        animator.start();
    }

    public void startWithType(int type) {
        if (type == 1) {
//            cameraFile = PhotoUtil.selectPicFromCamera(this, type);
        } else if (type == 2) {
//            PhotoUtil.selectPicFromLocal(this, type);
        }
    }

}
